#include "jinterfacestrategy.h"
#include "jabstractinterfacecaller.h"
#include <QTECore/jlog.h>

namespace QTE
{

class JInterfaceStrategyPriavte
{
public:
	~JInterfaceStrategyPriavte()
	{
		if( m_interface )
			m_interface->deleteLater();
	}

public:
	QString m_ifName;
	JAbstractInterfaceCaller *m_interface = nullptr;
	bool m_deleteOnFinished = true;
};

/*-------------------------------------------------------------------------------------------------------------------*/

JInterfaceStrategy::~JInterfaceStrategy()
{
	delete d_ptr;
}

QVariant JInterfaceStrategy::call()
{
	if( d_ptr->m_interface )
	{
		auto res = d_ptr->m_interface->call();

		if( d_ptr->m_deleteOnFinished )
			this->deleteLater();

		return res;
	}

	jError() << QString("JInterfaceStrategy: call: interface is NULL. (%1)").arg(d_ptr->m_ifName);
	return QVariant();
}

bool JInterfaceStrategy::isValid() const
{
	return d_ptr->m_interface != nullptr;
}

bool JInterfaceStrategy::deleteOnFinished() const
{
	return d_ptr->m_deleteOnFinished;
}

void JInterfaceStrategy::setDeleteOnFinished(bool enable)
{
	d_ptr->m_deleteOnFinished = enable;
}

void JInterfaceStrategy::setObject(const QString &ifName, QObject *obj)
{
	if( d_ptr == nullptr )
		d_ptr = new JInterfaceStrategyPriavte();
	d_ptr->m_ifName = ifName;

	if( obj == nullptr )
		return ;

	d_ptr->m_interface = J_OCT(JAbstractInterfaceCaller*, obj);

	if( d_ptr->m_interface == nullptr )
	{
		jError() << QString("JInterfaceStrategy: Object create failed. (%1) [type error]:").arg(ifName) << obj;

		if( d_ptr->m_deleteOnFinished )
			deleteLater();
	}
}

#define __CALL_ASYNC(_obj) \
	if( d_ptr->m_interface ) { \
		d_ptr->m_interface->call(_obj, [this, callBack](const QVariant &result) mutable { \
			if( callBack ) \
				callBack(result); \
			if( d_ptr->m_deleteOnFinished ) \
				this->deleteLater(); \
		}); \
	} else { \
		jError() << QString("JInterfaceStrategy: call: interface is NULL. (%1)").arg(d_ptr->m_ifName); \
	}

void JInterfaceStrategy::__call(const std::function<void (const QVariant&)> &callBack)
{
	__CALL_ASYNC(this);
}

void JInterfaceStrategy::__call(const QObject *obj, const std::function<void (const QVariant&)> &callBack)
{
	Q_ASSERT(obj);
	__CALL_ASYNC(obj);
}

void JInterfaceStrategy::__warning(const QString &ifName) const
{
	jWarning() << QString("JInterfaceStrategy: ObjectFactory: The type is not register. (%1)").arg(ifName);
}

} //namespace QTE
